﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FrogEngine
{
	public abstract class GameEntityServiceBase<T> : IGameEntityService, IDisposable
	{
		public GameEntityServiceBase(IEngine engine)
		{
			this.engine = engine;
			subscribedEntities = new HashSet<IGameEntity>();
			this.serviceOrder = 0;
		}

		protected IEngine engine;
		public IEngine Engine
		{
			get { return engine; }
		}

		protected HashSet<IGameEntity> subscribedEntities;
		public ISet<IGameEntity> SubscribedEntities
		{
			get { return subscribedEntities; }
		}

		public virtual bool Subscribe(IGameEntity entity)
		{
			if (entity is T)
			{
				if (subscribedEntities.Contains(entity))
					return false;
				subscribedEntities.Add(entity);
				entity.IDied += EntityDied;
				return true;
			}
			else
				throw new EntityCompatibilityException(entity.GetType(), this.GetType());
		}

		private void EntityDied(object sender, EventArgs args)
		{
			IGameEntity entity = sender as IGameEntity;
			if (entity != null)
			{
				Unsubscribe(entity);
				entity.IDied -= EntityDied;
			}
		}

		public virtual bool Unsubscribe(IGameEntity entity)
		{
			try
			{
				subscribedEntities.Remove(entity);
				return true;
			}
			catch
			{
				return false;
			}
		}

		protected int serviceOrder;
		public int ServiceOrder
		{
			get { return serviceOrder; }
		}

		public virtual void Dispose()
		{

		}
	}

	public abstract class GameEntityServiceBase : IGameEntityService, IDisposable
	{
		public GameEntityServiceBase(IEngine engine)
		{
			this.engine = engine;
			subscribedEntities = new HashSet<IGameEntity>();
			this.serviceOrder = 0;
		}

		protected IEngine engine;
		public IEngine Engine
		{
			get { return engine; }
		}

		protected HashSet<IGameEntity> subscribedEntities;
		public ISet<IGameEntity> SubscribedEntities
		{
			get { return subscribedEntities; }
		}

		public virtual bool Subscribe(IGameEntity entity)
		{
			subscribedEntities.Add(entity);
			entity.IDied += EntityDied;
			return true;
		}

		private void EntityDied(object sender, EventArgs args)
		{
			IGameEntity entity = sender as IGameEntity;
			if (entity != null)
			{
				Unsubscribe(entity);
				entity.IDied -= EntityDied;
			}
		}

		public virtual bool Unsubscribe(IGameEntity entity)
		{
			try
			{
				subscribedEntities.Remove(entity);
				return true;
			}
			catch
			{
				return false;
			}
		}

		protected int serviceOrder;
		public int ServiceOrder
		{
			get { return serviceOrder; }
		}

		public virtual void Dispose()
		{
			
		}
	}
}
